/*
 * CS_REQ_WORLD_BOSS_PARTY_JOIN_V2.cpp
 *
 *  Created on: 2014. 2. 13.
 *      Author: jjaehuny
 */





#include "../../Command.h"

#include "../../User.h"
#include "../../NLogic/Space.h"
#include "../../NLogic/Static.h"
#include "../../NLogic/Stamina.h"

#include "Common.h"
#include "../../constant.h"

namespace ProjectZ { namespace NCommand {

static void ACK_CS_REQ_WORLD_BOSS_PARTY_JOIN_V2(User * pUser, int16_t ack)
{
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pAck << static_cast<int16_t>(ack);
	pAck->MakePacket(CMD_SC_REQ_WORLD_BOSS_PARTY_JOIN_V2);
	pUser->Send(pAck);
}

void Command::CS_REQ_WORLD_BOSS_PARTY_JOIN_V2(User * pUser, ::Network::Packet * pPacket)
{
	/*
	CS_REQ_WORLD_BOSS_PARTY_JOIN_V2                 0x401B
	{
			   u32 u32room_number;
	}

	SC_REQ_WORLD_BOSS_PARTY_JOIN_V2                 0x401C
	{
			   s16 sAck;                                                    /// 이미 시작된 파티 등의 ack값 ACK_START_BATTLE, ACK_NOT_PARTY, ACK_BATTLE_AFTEREFFECT
			   u32 u32room_number;
			   u8 u8party_member_num;           /// min 1 , max 2 본인 제외
			   u8 count;                                                    /// ack 1이 아닌경우 0 그외 파티원 수만큼  방장을 가장 앞에 넣어 주세요...
			   {
						 u32 u32gid;                                       /// 본인을 포함한 파티원 gid정보
			   }
			   u8 u8remain_time;                               /// 남은 시간 초단위
	}
	*/

	NLogic::Space * pWorld = pUser->GetSpace();
	if (NULL == pWorld)
	{
		DEBUGLOG("%s NULL == pWorld", __FUNCTION__);
		ACK_CS_REQ_WORLD_BOSS_PARTY_JOIN_V2(pUser, ACK_NO_SPACE);
		return;
	}

	if (pWorld->GetData()._spaceType != NLogic::Space::SpaceType::WORLD)
	{
		DEBUGLOG("%s pWorld->GetData()._spaceType != NLogic::Space::SpaceType::WORLD", __FUNCTION__);
		ACK_CS_REQ_WORLD_BOSS_PARTY_JOIN_V2(pUser, ACK_NO_SPACE);
		return;
	}

	if (pUser->GetEnumState() != User::EnumState::__NONE__)
	{
		DEBUGLOG("%s pUser->GetEnumState() != User::EnumState::__NONE__", __FUNCTION__);
		ACK_CS_REQ_WORLD_BOSS_PARTY_JOIN_V2(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NLogic::Battle * pBattle = pUser->GetBattle();
	if (NULL == pBattle)
	{
		DEBUGLOG("%s NULL == pBattle", __FUNCTION__);
		ACK_CS_REQ_WORLD_BOSS_PARTY_JOIN_V2(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NLogic::Stamina * pStamina = pUser->GetStamina();
	if (NULL == pStamina)
	{
		DEBUGLOG("%s NULL == pStamina", __FUNCTION__);
		ACK_CS_REQ_WORLD_BOSS_PARTY_JOIN_V2(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	if (true == pStamina->IsKeyLack(1))
	{
		DEBUGLOG("%s staminaGap < 0", __FUNCTION__);
		ACK_CS_REQ_WORLD_BOSS_PARTY_JOIN_V2(pUser, ACK_NOT_ENOUGHT_STAMINA);
		return;
	}

/*	time_t currentSec;
	time(&currentSec);

	// 현재 스태미너가 최대라면 남은 회복 시간을 현재시간으로 설정
	if (pUser->GetCharacterInfo().event_stamina == STAMINA_MAX)
		pUser->GetCharacterInfo().recover_stamina_sec = currentSec;

	int staminaGap = pUser->GetCharacterInfo().event_stamina - 1;

	// 보유 스태미너가 부족한 경우
	if (staminaGap < 0)
	{
		DEBUGLOG("%s staminaGap < 0", __FUNCTION__);
		ACK_CS_REQ_WORLD_BOSS_PARTY_JOIN_V2(pUser, ACK_NOT_ENOUGHT_STAMINA);
		return;
	}*/

	PREPARE_PACKET;

	uint32_t u32room_number = 0;
	* pPacket >> u32room_number;

	NLogic::Static::WORLDBOSSROOMTREE & worldBossRoomTree = NLogic::Static::Instance().GETWORLDBOSSROOMTREE();
	auto itr = worldBossRoomTree.find(u32room_number);
	if (itr == worldBossRoomTree.end())
	{
		ACK_CS_REQ_WORLD_BOSS_PARTY_JOIN_V2(pUser, ACK_NOT_PARTY);
		return;
	}

	NLogic::Space * pWorldBossSpace = itr->second;

	NLogic::Party * pParty = pWorldBossSpace->GetParty();
	if (NULL == pParty)
	{
		ACK_CS_REQ_WORLD_BOSS_PARTY_JOIN_V2(pUser, ACK_NOT_PARTY);
		return;
	}

	if (NLogic::Party::State::WORLD_BOSS_WAIT != pParty->GetState())
	{
		ACK_CS_REQ_WORLD_BOSS_PARTY_JOIN_V2(pUser, ACK_START_BATTLE);
		return;
	}

	if (static_cast<int>(pParty->GetAllUserTree().size()) >= pWorldBossSpace->GetData()._maxUser + 1)
	{
		ACK_CS_REQ_WORLD_BOSS_PARTY_JOIN_V2(pUser, ACK_START_BATTLE);
		return;
	}

	User * pMaster = pParty->GetMaster();
	if (NULL == pMaster)
	{
		ACK_CS_REQ_WORLD_BOSS_PARTY_JOIN_V2(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	pParty->EnterUser(pUser);
	pParty->AddInviteUserTree(pUser);

	auto partyAllUserTree = pParty->GetAllUserTree();
	{
		::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
		* pAck << static_cast<int16_t>(ACK_OK);
		* pAck << static_cast<uint32_t>(pWorldBossSpace->GetIndexerWorldBoss()->GetIndex());
		* pAck << static_cast<uint8_t>(pWorldBossSpace->GetData()._maxUser);

		uint8_t count = partyAllUserTree.size();

		uint32_t u32gid = static_cast<uint32_t>(pMaster->GetUserSeq());
		* pAck << static_cast<uint8_t>(count);
		* pAck << u32gid;

		std::for_each(partyAllUserTree.begin(), partyAllUserTree.end(), [&](NLogic::Party::USERTREE::value_type & pair) {
			User * pUser = pair.second;

			if ( pUser != pMaster)
			{
				uint32_t u32gid = static_cast<uint32_t>(pUser->GetUserSeq());

				* pAck << u32gid;
			}
		} );

		* pAck << static_cast<uint8_t>(pParty->GetRoomWaitEndTime() - time(NULL));
		pAck->MakePacket(CMD_SC_REQ_WORLD_BOSS_PARTY_JOIN_V2);
		pUser->Send(pAck);
	}

	SendWorldBossDetailInfo(pUser);

	{	// send sn party join
		::Network::Packet * pNoti = ::Network::GETPACKETPOOL()->SEND_NEW();
		* pNoti << pUser->GetUserSeq();
		pNoti->MakePacket(CMD_SN_REQ_WORLD_BOSS_PARTY_JOIN);
		pWorldBossSpace->SendAllExceptMe(pNoti, pUser);
	}

	pWorld->LeaveUser(pUser);
	pWorldBossSpace->EnterUser(pUser);

	pBattle->GetData().bReadyFight = false;

	pUser->SetEnumState(User::EnumState::ACCEPT_WAIT);
}

} /*NCommand*/ } /*ProjectZ*/


